home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
emerald
/
emrldsys.lha
/
Language
/
Compiler
/
construct.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-16
|
8KB
|
312 lines
/*
* @(#)construct.c 1.5 1/20/89
*/
#include "assert.h"
#include "nodes.h"
#include "keyword.h"
#include "system.h"
#include "sequence.h"
#include "semantics.h"
NodePtr RCONS(list, anElement)
NodePtr list, anElement;
{
register NodePtr newlist;
register int length;
if (list == NULL) {
newlist = F_NewNode(T_SEQUENCE, 4);
} else if (list->nChildren >= list->maxChildren) {
length = list->maxChildren;
newlist = F_NewNode(list->tag, 2 * length);
bcopy((char *)list, (char *)newlist, NodeSize(list));
newlist->maxChildren = 2 * length;
free((char *)list);
} else {
newlist = list;
}
if (newlist->nChildren == 0 && (int) anElement > 0x200)
newlist->lineNumber = anElement->lineNumber;
newlist->b.children[newlist->nChildren] = anElement;
newlist->nChildren++;
return(newlist);
}
NodePtr RAPPEND(list, listOrElement)
NodePtr list, listOrElement;
{
register NodePtr q;
if (! isASequence(list)) {
q = F_NewNode(T_SEQUENCE, 4);
q->nChildren = 1;
q->b.children[0] = list;
list = q;
}
if (listOrElement == NULL)
return(list);
if ((int)listOrElement <= 0x200 || listOrElement->tag != T_SEQUENCE)
return(RCONS(list, listOrElement));
Sequence_For(q, listOrElement)
list = RCONS(list, q);
Sequence_Next
free((char *)listOrElement);
return(list);
}
/*VARARGS2*/
NodePtr Construct(t, nargs, therest)
Tag t;
int nargs;
NodePtr therest;
{
register NodePtr *args = &therest;
register NodePtr p;
register int i;
int minLineNumber;
p = F_NewNode(t, nargs);
minLineNumber = p->lineNumber;
for (i = 0; i < nargs; i++) {
p->b.children[p->firstChild+i] = args[i];
if ((int) args[i] > 0x200 && args[i]->lineNumber < minLineNumber)
minLineNumber = args[i]->lineNumber;
}
p->nChildren += nargs;
p->lineNumber = minLineNumber;
return (p);
}
NodePtr makeOpName(p)
NodePtr p;
{
register NodePtr result;
if ((int) p <= 0x200) {
result = Construct(P_OPNAME, 0);
result->b.opname.ident = (int)p - firstKeyword;
return(result);
} else if (p->tag == T_IDENT) {
result = Construct(P_OPNAME, 0);
result->b.opname.ident = p->b.ident.ident;
free((char *)p);
return(result);
} else {
assert (p->tag == P_OPNAME);
return(p);
}
}
/*
* fD1 is a primary, fD2 is a sequence of selections. Each selection is:
* P_SELECTION NULL opname argumentlist
* P_FIELDSEL NULL identifier
* P_SUBSCRIPT NULL expression
* We want to build the unsugared node, either:
* P_INVOC rest opname argumentlist
* P_FIELDSEL rest identifier
* P_SUBSCRIPT rest expression
*/
NodePtr buildSelection(fD1, fD2)
NodePtr fD1, fD2;
{
Tag tag;
register NodePtr result, thisOne, q;
result = fD1;
Sequence_For(thisOne, fD2)
tag = thisOne->tag;
switch (tag) {
case P_SELECTION:
q = Construct(P_INVOC, 3, result,
thisOne->b.selection.opname, thisOne->b.selection.args);
q->lineNumber = thisOne->lineNumber;
free((char *) thisOne);
thisOne = q;
break;
case P_FIELDSEL:
thisOne->b.fieldsel.target = result;
break;
case P_SUBSCRIPT:
thisOne->b.subscript.target = result;
break;
default:
assert(FALSE);
break;
}
result = thisOne;
Sequence_Next
Free(fD2);
return(result);
}
/*
* fD1 is a list of operators, fD2 is an expression. We want to build
* P_INVOC rest opname null
*/
NodePtr buildExpression1(fD1, fD2)
NodePtr fD1, fD2;
{
NodePtr result, operator;
if (fD1 == NULL) return (fD2);
result = fD2;
Sequence_ReverseFor(operator, fD1)
if ((int) operator == KLOCATE || (int) operator == KISFIXED ||
(int) operator == KAWAITING) {
result = Construct(P_UNARYEXP, 2, operator, result);
} else {
result = Construct(P_INVOC, 3, result, makeOpName(operator), NULL);
}
Sequence_Next
Free(fD1);
return(result);
}
/*
* Here there are a couple of cases. If the operation name is one of the
* funny control flow ones KAND, KOR, OIDENTITY, ONOTIDENTITY, OCONFORMSTO
* then we want to build a special node. Otherwise we treat it like in
* buildExpression1.
* Here fD1 is a sequence of expressions separated by operators.
*/
NodePtr buildExpression2(fD1)
NodePtr fD1;
{
register int i, maxIndex;
register NodePtr result, operation, argument;
Tag tag;
assert(fD1->firstChild == 0);
result = fD1->b.children[0];
maxIndex = fD1->nChildren - 1;
for (i = 1; i <= maxIndex ; i += 2) {
operation = fD1->b.children[i];
argument = fD1->b.children[i + 1];
if ((int) operation == KAND || (int) operation == KOR ||
(int) operation == OIDENTITY || (int) operation == ONOTIDENTITY ||
(int) operation == OCONFORMSTO) {
tag = P_EXP;
} else {
tag = P_INVOC;
operation = makeOpName(operation);
argument = Construct(T_SEQUENCE, 1, Construct(P_ARG, 1, argument));
}
result = Construct(tag, 3, result, operation, argument);
}
Free(fD1);
return(result);
}
NodePtr Flatten(fSeq)
NodePtr fSeq;
{
register NodePtr q, r, result;
register int count = 0;
assert(fSeq->tag == T_SEQUENCE);
Sequence_For(q, fSeq)
if (q->tag == T_SEQUENCE) {
count += q->nChildren;
} else {
count ++;
}
Sequence_Next
if (count == fSeq->nChildren) return(fSeq);
result = F_NewNode(T_SEQUENCE, count);
result->nChildren = count;
count = 0;
Sequence_For(q, fSeq)
if ((int)q >= 0x200 && q->tag == T_SEQUENCE) {
Sequence_For(r, q)
result->b.children[count++] = r;
Sequence_Next
free((char *)q);
} else {
result->b.children[count++] = q;
}
Sequence_Next
assert(count == result->nChildren);
free((char *)fSeq);
return(result);
}
NodePtr Distribute(fTag, fSeq, nArgs, firstArg)
Tag fTag;
NodePtr fSeq, firstArg;
int nArgs;
{
register int i, j;
register NodePtr *args = &firstArg;
register NodePtr result, thisOne;
assert(fSeq->tag == T_SEQUENCE);
if (fSeq->nChildren == 1) {
result = F_NewNode(fTag, nArgs+1);
result->nChildren += nArgs+1;
result->b.children[result->firstChild] = fSeq->b.children[0];
result->lineNumber = fSeq->b.children[0]->lineNumber;
for (j = 0; j < nArgs; j++)
result->b.children[result->firstChild+j+1] = args[j];
free((char *)fSeq);
} else {
result = F_NewNode(T_SEQUENCE, fSeq->nChildren);
result->nChildren = fSeq->nChildren;
for (i = 0; i < fSeq->nChildren; i++) {
thisOne = F_NewNode(fTag, nArgs + 1);
result->b.children[i] = thisOne;
thisOne->nChildren += nArgs + 1;
thisOne->b.children[thisOne->firstChild] = fSeq->b.children[i];
thisOne->lineNumber = fSeq->b.children[i]->lineNumber;
for (j = 0; j < nArgs; j++)
thisOne->b.children[thisOne->firstChild+j+1] = args[j];
}
result->lineNumber = result->b.children[0]->lineNumber;
free((char *)fSeq);
}
return(result);
}
NodePtr Copy(fNode)
register NodePtr fNode;
{
register NodePtr result;
register int i;
if ((int) fNode <= 0x200) return(fNode);
else {
result = F_NewNode(fNode->tag, fNode->nChildren-fNode->firstChild);
result->nChildren = fNode->nChildren;
for (i = 0; i < fNode->firstChild; i++) {
result->b.children[i] = fNode->b.children[i];
}
for (i = fNode->firstChild; i < fNode->nChildren; i++) {
result->b.children[i] = Copy(fNode->b.children[i]);
}
return(result);
}
}
NodePtr Copy1Node(fNode)
register NodePtr fNode;
{
register NodePtr result;
if ((int) fNode <= 0x200) return(fNode);
else {
result = F_NewNode(fNode->tag, fNode->nChildren-fNode->firstChild);
bcopy((char *)fNode, (char *)result, NodeSize(fNode));
return(result);
}
}
NodePtr singleArg(n)
NodePtr n;
{
return(Construct(T_SEQUENCE, 1, (Construct(P_ARG, 1, n))));
}
NodePtr buildString(s)
char *s;
{
NodePtr r;
r = Construct(P_STRINGLIT, 0);
r->b.stringlit.string = malloc(strlen(s) + 1);
strcpy(r->b.stringlit.string, s);
return(r);
}